// -----------------------------------------------------------------------
// <copyright file="PhoneNumberManager.cs" company="Imar.Spaanjaars.Com">
//   Copyright 2008 - 2009 - Imar.Spaanjaars.Com. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------

using System;
using System.ComponentModel;
using Spaanjaars.ContactManager.BusinessEntities;
using Spaanjaars.ContactManager.Dal;
using System.Collections.Generic;
using Spaanjaars.Validation;

namespace Spaanjaars.ContactManager.Bll
{
  /// <summary>
  /// The PhoneNumberManager class is responsible for managing BusinessEntities.PhoneNumber objects in the system.
  /// </summary>
  [DataObjectAttribute()]
  public static class PhoneNumberManager
  {
    #region Public Methods

		/// <summary>
		/// Gets a list with PhoneNumber objects for the requested contact person.
		/// </summary>
		/// <param name="contactPersonId">The ID of the ContactPerson for whom the phonenumbers should be returned.</param>
		/// <returns>A list with PhoneNumber objects when the database contains phonenumbers for the contact person, or an empty list otherwise.</returns>
		[DataObjectMethod(DataObjectMethodType.Select, true)]
		public static PhoneNumberCollection GetList(int contactPersonId)
		{
			return GetList(contactPersonId, string.Empty);
		}

		/// <summary>
		/// Gets a list with PhoneNumber objects for the requested contact person.
		/// </summary>
		/// <param name="contactPersonId">The ID of the ContactPerson for whom the phonenumbers should be returned.</param>
		/// <param name="sortExpression">A string containing the expression to sort on. Can contain desc to indicarte descneding order.</param>
		/// <returns>A list with PhoneNumber objects when the database contains phonenumbers for the contact person, or an empty list otherwise.</returns>
		[DataObjectMethod(DataObjectMethodType.Select, false)]
		public static PhoneNumberCollection GetList(int contactPersonId, string sortExpression)
		{
			PhoneNumberCollection myCollection = PhoneNumberDB.GetList(contactPersonId);
			if (!string.IsNullOrEmpty(sortExpression))
			{
				myCollection.Sort(new PhoneNumberComparer(sortExpression));
			}
			return myCollection;
		}

		/// <summary>
    /// Gets a single PhoneNumber from the database.
    /// </summary>
    /// <param name="id">The unique ID of the phone number in the database.</param>
    /// <returns>An PhoneNumber object when the ID exists in the database, or <see langword="null"/> otherwise.</returns>
    [DataObjectMethod(DataObjectMethodType.Select, false)]
    public static PhoneNumber GetItem(int id)
    {
      return PhoneNumberDB.GetItem(id);
    }

    /// <summary>
    /// Saves a phone number in the database.
    /// </summary>
    /// <param name="myPhoneNumber">The PhoneNumber instance to save.</param>
    /// <returns>The new ID of the PhoneNumber is new in the database or the existing ID when an item was updated.</returns>
    [DataObjectMethod(DataObjectMethodType.Update, true)]
    public static int Save(PhoneNumber myPhoneNumber)
    {
			if (myPhoneNumber.Validate())
			{
				myPhoneNumber.Id = PhoneNumberDB.Save(myPhoneNumber);
				return myPhoneNumber.Id;
			}
			else
			{
				throw new InvalidSaveOperationException("Can't save an invalid PhoneNumber. Please make sure IsValid() returns true before you call Save.");
			}
    }

    /// <summary>
    /// Deletes a phone number from the database.
    /// </summary>
    /// <param name="myPhoneNumber">The PhoneNumber instance to delete.</param>
    /// <returns>Returns <c>true</c> when the object was deleted successfully, or <c>false</c> otherwise.</returns>
    [DataObjectMethod(DataObjectMethodType.Delete, true)]
    public static bool Delete(PhoneNumber myPhoneNumber)
    {
      return PhoneNumberDB.Delete(myPhoneNumber.Id);
    }

    #endregion

		#region IComparable

		/// <summary>
		/// Implements IComparer&lt;PhoneNumber&gt; to allow PhoneNumber objects to be sorted.
		/// </summary>
		private class PhoneNumberComparer : IComparer<PhoneNumber>
		{
			private string _sortColumn;
			private bool _reverse;
			/// <summary>
			/// Constructor for the PhoneNumberComparer class that expects the property of the PhoneNumber class to sort on.
			/// </summary>
			/// <param name="sortExpression">Contains the property of the PhoneNumber class to sort on. Append [space]desc to sort in reversed order.</param>
			public PhoneNumberComparer(string sortExpression)
			{
				if (string.IsNullOrEmpty(sortExpression))
				{
					sortExpression = "Id desc";
				}
				_reverse = sortExpression.ToUpperInvariant().EndsWith(" desc", StringComparison.OrdinalIgnoreCase);
				if (_reverse)
				{
					_sortColumn = sortExpression.Substring(0, sortExpression.Length - 5);
				}
				else
				{
					_sortColumn = sortExpression;
				}
			}

			/// <summary>
			/// Compares two instances of PhoneNumber.
			/// </summary>
			/// <param name="x">The left hand side PhoneNumber object.</param>
			/// <param name="y">The right hand side PhoneNumber object.</param>
			public int Compare(PhoneNumber x, PhoneNumber y)
			{
				int retVal = 0;
				switch (_sortColumn.ToUpperInvariant())
				{
					case "ID":
						retVal = x.Id.CompareTo(y.Id);
						break;
					case "NUMBER":
						retVal = string.Compare(x.Number, y.Number, StringComparison.OrdinalIgnoreCase);
						break;
					case "TYPE":
						retVal = x.Type.CompareTo(y.Type);
						break;
					case "CONTACTPERSONID":
						retVal = x.ContactPersonId.CompareTo(y.ContactPersonId);
						break;
				}
				int _reverseInt = 1;
				if ((_reverse))
				{
					_reverseInt = -1;
				}
				return (retVal * _reverseInt);
			}
		}
		#endregion
  }
}